﻿using System;
using System.Net;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel.Composition;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Details;
using System.Windows;
using System.Threading;

namespace ExtensionsMadeEasy.Navigation
{
    [Export(typeof(IEntityOpener))]
    public class EntityOpener : IEntityOpener
    {
        public bool NavigateTo(string entityName, string dataSourceName, params object[] singleOrDefaultQueryArguments)
        {
            var dataWorkspace = global::Microsoft.LightSwitch.Framework.Base.ApplicationProvider.Current.CreateDataWorkspace();
            IDataService dataService = dataWorkspace.Details.Properties[dataSourceName].Value as IDataService;
            return NavigateTo(entityName, dataService, singleOrDefaultQueryArguments);
        }

        public bool NavigateTo(string entityName, IDataService dataService, params object[] singleOrDefaultQueryArguments) {
            if (string.IsNullOrEmpty(entityName) || null == dataService)
                return false;

            ICreateQueryMethodInvocation query = GetEntityQuery(dataService, entityName, singleOrDefaultQueryArguments);
            if (query != null) { 
                if(Microsoft.LightSwitch.Threading.Dispatchers.Current.Equals(query.Dispatcher)){
                    IEntityObject entityObject = query.Execute() as IEntityObject;
                    NavigateToEntity(entityObject);
                }
                else{
                    query.Dispatcher.BeginInvoke(
                    () => {
                        try
                        {
                            IEntityObject entityObject = query.Execute() as IEntityObject;
                            NavigateToEntity(entityObject);
                        }
                        catch (Exception x) {
                            throw x; //intercepting for debug only... The exception will likely go lost anyways (threading :'( )
                        }
                    });
                }
            }
            return false;            
        }
        private static void NavigateToEntity(IEntityObject entity) {
            dynamic d = global::Microsoft.LightSwitch.Framework.Base.ApplicationProvider.Current;
            d.ShowDefaultScreen(entity);
        }
        private static ICreateQueryMethodInvocation GetEntityQuery(IDataService dataService, string entitySetName, params object[] singleOrDefaultQueryArguments)
        { 
            ICreateQueryMethod singleOrDefaultQuery = dataService.Details.Methods[entitySetName + "_SingleOrDefault"] as ICreateQueryMethod;
            return singleOrDefaultQuery.CreateInvocation(singleOrDefaultQueryArguments);
        }
    }
}
